import { EventCenterMicroApp } from "./data";
import { isClass, isConstructor } from "./utils";

// js 隔离
export default class SandBox {
  microWindow: any = {};
  proxyWindow: any;

  constructor(appName: string) {
    this.microWindow.microApp = new EventCenterMicroApp(appName);
    this.proxyWindow = this.getProxyWindow();
  }

  run(code: string) {
    const fn = new Function(
      "window",
      `with (window) {
        ${code}
      }`
    );

    fn.call(this.proxyWindow, this.proxyWindow);
  }

  getProxyWindow() {
    return new Proxy(this.microWindow, {
      get(microWindow, key) {
        if (Reflect.has(microWindow, key)) {
          return Reflect.get(microWindow, key);
        }

        const rawValue = Reflect.get(window, key);
        if (typeof rawValue !== "function") return rawValue;
        if (isConstructor(rawValue)) return; // 排除构造函数
        if (isClass(rawValue)) return; // 排除类

        return rawValue.bind(window);
      },
      set(microWindow, key, value) {
        return Reflect.set(microWindow, key, value);
      },
      deleteProperty(microWindow, key) {
        if (microWindow.hasOwnProperty(key)) {
          return Reflect.deleteProperty(microWindow, key);
        }
        return true;
      },
    });
  }
}
